package com.ebupt.migu.music.propagate.schedule;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.ebupt.migu.music.commons.constants.StrategyConstants;
import com.ebupt.migu.music.commons.utils.CSVUtils;
import com.ebupt.migu.music.propagate.dto.SendDto;
import com.ebupt.migu.music.propagate.mapper.MegamaketConfMapper;
import com.ebupt.migu.music.propagate.mapper.PropagateInfoMapper;
import com.ebupt.migu.music.propagate.mapper.PropagateStrategyMapper;
import com.ebupt.migu.music.propagate.service.PropagateSendService;
import com.ebupt.migu.propagate.PropagateRedisBean;
import com.ebupt.migu.propagate.PropagateStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tz
 */
@Slf4j
@Service
public class DetailToRedis {

    @Resource
    private PropagateSendService propagateSendService;
    @Resource
    private PropagateStrategyMapper propagateStrategyMapper;
    @Resource
    private PropagateInfoMapper propagateInfoMapper;
    @Resource
    private MegamaketConfMapper megamaketConfMapper;
    @Resource
    private RedisTemplate redisTemplate;

    public void setPropagateToRedis() {
        //查询符合入redis的活动信息
        List<PropagateStrategy> ps = propagateStrategyMapper.qryByStatus(4);
        Set<Object> newSet = new HashSet<>();
        if (ps == null || ps.size() < 1) {
            log.info("没有可缓存的宣发策略信息");
        } else {
            ps.forEach(e -> {
                PropagateRedisBean redisBean = new PropagateRedisBean();
                BeanUtils.copyProperties(e,redisBean);
                redisBean.setInfos(propagateInfoMapper.qryByStrategyId(e.getStrategyId()));
                redisBean.setConf(megamaketConfMapper.qryById(e.getSendPort()));
                String redisKey = "propagate-" + e.getStrategyId();
                redisTemplate.opsForValue().set(redisKey,JSON.toJSONString(redisBean));
                newSet.add(redisKey);
            });
        }
        // 判断set集合key是否存在，求差集删除过期key
        if (redisTemplate.hasKey(StrategyConstants.STRATEGY_LIST)){
            Set<Object> hasSet = redisTemplate.opsForSet().members(StrategyConstants.STRATEGY_LIST);
            hasSet.removeAll(newSet);
            hasSet.forEach(e -> {
                if (redisTemplate.hasKey(e.toString())){
                    redisTemplate.delete(e.toString());
                }
            });
            for (Object o : hasSet) {
                redisTemplate.opsForSet().remove(StrategyConstants.STRATEGY_LIST,o);
            }
        }
        // 更新集合
        if (newSet.size() > 0) {
            for (Object o : newSet) {
                redisTemplate.opsForSet().add(StrategyConstants.STRATEGY_LIST,o);
            }
            log.info("宣发缓存列表redis更新成功");
        }
    }

    public void updateStrategyStatus(){
        Date now = new Date();
        //查询未开始的策略
        List<PropagateStrategy> p1 = propagateStrategyMapper.qryByStatus(3);
        p1.forEach(e -> {
            if (DateUtil.parse(e.getStartTime(), "yyyy-MM-dd").before(now)) {
                if (e.getActivationCodeType() == 1) {
                    //利用redis单线程防止分布式更新数据
                    if (!redisTemplate.hasKey(e.getActivationCodeKey())){
                        // excel导入激活码，读取文件并存入redis
                        List<String[]> ls = CSVUtils.csvRead(e.getActivationCodePath());
                        // 删除表头
                        ls.remove(0);
                        // 只取文件第一列数据
                        List<String> collect = ls.stream().map(s -> s[0]).collect(Collectors.toList());
                        // 存入redis队列
                        redisTemplate.opsForList().leftPushAll(e.getActivationCodeKey(),collect);
                    }
                }
                e.setExecuteStatus(4);
                propagateStrategyMapper.updateById(e);
            }
        });
        //查询进行中的策略
        List<PropagateStrategy> p2 = propagateStrategyMapper.qryByStatus(4);
        p2.forEach(e -> {
            if (DateUtil.offsetDay(DateUtil.parse(e.getEndTime(), "yyyy-MM-dd"), 1).before(now)) {
                e.setExecuteStatus(6);
                propagateStrategyMapper.updateById(e);
                if (e.getActivationCodeType() == 1) {
                    //已完成的策略删除缓存的激活码redis队列
                    redisTemplate.unlink(e.getActivationCodeKey());
                }
            }
        });
    }

    public void sendCache(){
        //获取缓存key里面所有的调用
        while (true){
            Object o = redisTemplate.opsForList().rightPop(StrategyConstants.PROPAGATE_CACHE);
            if (Optional.ofNullable(o).isPresent()) {
                SendDto dto = JSON.parseObject(o.toString(), SendDto.class);
                propagateSendService.send(dto);
            } else {
                break;
            }
        }
    }

}
